package org.xiaov.lunasql.engine.function;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import org.xiaov.lunasql.engine.ast.IntervalAdjust;

import java.util.List;

/**
 * <p>
 * DateOperateFunc
 * </p>
 *
 * @author LunaSQL
 * @since 2024/12/15 16:56
 */
public abstract class DateOperateFunc implements MySqlFunction {
    private final String op;
    private final String sourceName;
    private final String targetName;
    private final List<MySqlFunction> functions;
    private final IntervalAdjust intervalAdjust;

    /**
     * 构造方法
     *
     * @param op             op
     * @param sourceName     sourceName
     * @param targetName     targetName
     * @param functions      functions
     * @param intervalAdjust intervalAdjust
     */
    public DateOperateFunc(String op, String sourceName, String targetName,
                           List<MySqlFunction> functions, IntervalAdjust intervalAdjust) {
        this.op = op;
        this.sourceName = sourceName;
        this.targetName = targetName;
        this.functions = functions;
        this.intervalAdjust = intervalAdjust;
    }

    @Override
    public boolean accept(SQLMethodInvokeExpr methodInvokeExpr) {
        return sourceName.equalsIgnoreCase(methodInvokeExpr.getMethodName());
    }

    @Override
    public void transform(SQLMethodInvokeExpr methodInvokeExpr) {
        List<SQLExpr> arguments = methodInvokeExpr.getArguments();
        SQLBinaryOpExpr sqlBinaryOpExpr = new SQLBinaryOpExpr();
        sqlBinaryOpExpr.setLeft(arguments.get(0));
        sqlBinaryOpExpr.setRight(arguments.get(1));
        sqlBinaryOpExpr.setOperator(SQLBinaryOperator.from(op));
        if (methodInvokeExpr.getParent() instanceof SQLReplaceable repeatable) {
            repeatable.replace(methodInvokeExpr, sqlBinaryOpExpr);
        }
    }
}
